#include "qbcitargetsgroup.h"
#include <QLogger>
#include <QTimer>

QBciTargetsGroup::QBciTargetsGroup(QObject *parent) : QObject(parent) {}

void QBciTargetsGroup::addTarget(QBciTargetInterface *target) {
  if (target->label() == "") {
    QLogger::Error("BciTargetsGroup::addTarget:"
                   "Cannot add a target with EMPTY label.");
    return;
  }
  TargetList.append(target);
}

void QBciTargetsGroup::removeTarget(QBciTargetInterface *target) {
  TargetList.removeAll(target);
}

void QBciTargetsGroup::removeTarget(const QString &label) {
  for (auto it = TargetList.begin(); it != TargetList.end(); ++it) {
    if ((*it)->label() == label) {
      it = TargetList.erase(it);
    }
  }
}

QBciTargetInterface *QBciTargetsGroup::getTarget(const QString &label) {
  if (label == "") {
    QLogger::Error("BciTargetsGroup::getTarget: Cannot search a target with "
                   "EMPTY label.");
    return nullptr;
  }
  for (auto it = TargetList.begin(); it != TargetList.end(); ++it) {
    if ((*it)->label() == label) {
      return *it;
    }
  }
  return nullptr;
}

QBciTargetInterface *QBciTargetsGroup::operator[](const QString &label) {
  return getTarget(label);
}

void QBciTargetsGroup::paint(QPainter *painter) {
  foreach (auto target, TargetList) { target->paint(painter); }
}

void QBciTargetsGroup::setEnableWave(const bool &flag) {  
  foreach (auto target, TargetList) {target->render->setEnableWave(flag, target->ID);}
}

void QBciTargetsGroup::setTarget(QBciTargetInterface *target) {
  if (target != nullptr) {
    target->set();
    emit update();
  }
}

void QBciTargetsGroup::setTarget(const QString &targetLabel) {
  setTarget(getTarget(targetLabel));
}
void QBciTargetsGroup::setTarget(QBciTargetInterface *target, int timeout) {
  assert(target);
  target->set();
  startTimer(target, timeout);
}
void QBciTargetsGroup::setTarget(const QString &targetLabel, int timeout) {
  setTarget(getTarget(targetLabel), timeout);
}

void QBciTargetsGroup::resetTarget(QBciTargetInterface *target) {
  if (target != nullptr) {
    target->reset();
    emit update();
  }
}

void QBciTargetsGroup::resetTarget(const QString &targetLabel) {
  resetTarget(getTarget(targetLabel));
}

void QBciTargetsGroup::setAllTarget() {
  foreach (auto target, TargetList)
    setTarget(target);
  emit update();
}

void QBciTargetsGroup::resetAllTarget() {
  foreach (auto target, TargetList)
    resetTarget(target);
  emit update();
}

void QBciTargetsGroup::startTimer(QBciTargetInterface *target, int timeout) {
  assert(timeout > 50); // not allow too short
  QSharedPointer<QTimer> timer = QSharedPointer<QTimer>::create();
  QUuid id = QUuid::createUuid();
  timer->setSingleShot(true);
  QObject::connect(timer.data(), &QTimer::timeout, this, [this, target, id]() {
    target->reset();
    this->endTimer(id);
  });
  timer->start(timeout);
  timerMap.insert(std::make_pair(id, timer));
}

void QBciTargetsGroup::endTimer(const QUuid &id) { timerMap.erase(id); }
